/**
 * Copyright (C) 2008+ Spark Zheng
 *
 * @file	include/conf.h
 * @brief
 *	config module, config file must like:
 *		#this is an annotation
 *		key1 = value1
 *		key2 = value2 \
 *		       value2-continued (need notice the space)
 *		key3 = value3-1, value3-2
 * 
 * @see		dlib
 * @module      dlib
 * @history
 *      version 0.0.1 2008-08-18, Spark init conf module.
 *
 */

#ifndef _DLIB_CONF_H
#define _DLIB_CONF_H

#ifdef __cplusplus
extern "C" {
#endif

#include "global.h"
#include "htable.h"
	
#define CONF_STR_MOVE	0		/** get string method, just move */
#define CONF_STR_COPY	1		/** get string method, need alloc&copy */

/** str and int structs */
typedef struct {
	char		*name;		/** conf item name */
	char		*defval;	/** conf item default value */
	char		*value;		/** conf item read-in value */
	int32_t		min;		/** conf item value min-length */
	int32_t		max;		/** conf item value max-length */
	uint32_t	index;		/** conf item index */
} dlib_conf_str_t;

typedef struct {
	char		*name;		/** conf item name */
	long		defval;		/** conf item default value */
	char		*value;		/** conf item read-in value */
	int32_t		min;		/** conf item value min-number */
	int32_t		max;		/** conf item value max-number */
	uint32_t	index;		/** conf item index */
} dlib_conf_int_t;

typedef union {
	dlib_conf_str_t	str_table;	/** string item */
	dlib_conf_int_t	int_table;	/** integer item(include bool) */
} dlib_conf_t;


/**
 * dlib_conf_init
 * @brief read the conf file and fill into htable, return 0 or err.
 * @param file: the config file path.
 * @param t: conf array of keywords and default values.
 * @param len: conf array length.
 * @param dict_len: htable span, usually a primer.
 */
extern htable_t *dlib_conf_init(const char *file, dlib_conf_t *t, uint32_t len,
				uint32_t dict_len);

/**
 * dlib_conf_get_integer
 * @brief get an integer from htable, return 0 or < 0(err).
 * @param dict: htable structure.
 * @param key: key to access value.
 * @param integer[OUT]: out container
 */
extern int dlib_conf_get_integer(htable_t *dict, const char *key, long *integer);

/**
 * dlib_conf_get_string
 * @brief get a string from htable, return the string or NULL.
 * @warning WARNING: the return string need to be freed by hand when it's not defval.
 * @param dict: htable structure.
 * @param key: key to access value.
 * @param type: get string method, MOVE(0) or COPY(1).
 *	MOVE means mv string from htable_node, COPY means alloc a buffer, and
 *	copy string from htable_node to buffer.
 *	BOTH method need to free return pointer by hand when it's not defval.
 */
extern char *dlib_conf_get_string(htable_t *dict, const char *key, int type);

/** 
 * dlib_conf_exit
 * @brief release the memory in dict
 * @param dict: htable structure.
 */
extern void dlib_conf_exit(htable_t *dict);

#ifdef __cplusplus
}
#endif
#endif
